import time

from ..exception.TestException import TestException
from ..common.ui.PageElement import PageElement
from ..exception.errorcode import ErrorCode


class Tree(PageElement):
    _fish_data_ui_role = 'tree'

    def select(self, *params):
        self.wait_element_presence()
        self.check_fish_data_role_id()
        if len(params) == 0:
            raise TestException.by_error_code(ErrorCode.TREE_NOT_PARAMS)
        datasource = self.__get_datasource()
        if not datasource:
            raise TestException.by_error_code(ErrorCode.TREE_NOT_DATA)
        self.__find_match_node(*params, datasource=datasource, matchIndex=0)

    def __find_match_node(self, *params, datasource, matchIndex: int, node_locate: str = ''):
        match = False
        for data in datasource:
            if data['name'] == params[matchIndex]:
                match = True
                if len(params) != matchIndex + 1:
                    if matchIndex == 0:
                        node_locate = '[{0}]'.format(datasource.index(data))
                    else:
                        node_locate = '{find}.children[{index}]'.format(find=node_locate, index=datasource.index(data))
                    self.__find_match_node(*params, datasource=data['children'], matchIndex=matchIndex + 1,
                                           node_locate=node_locate)
                else:
                    if matchIndex == 0:
                        node_locate = '[{0}]'.format(datasource.index(data))
                    else:
                        node_locate = '{find}.children[{index}]'.format(find=node_locate, index=datasource.index(data))
                    self.__select_node(node_locate)
                break
        if not match:
            raise TestException.by_error_code(ErrorCode.TREE_VALUE_NOT_FIND, value=params[matchIndex], data_source=datasource)

    def __select_node(self, node_locate):
        script = "var node = $(arguments[0]).tree('getNodes'){node_locate};" \
                 "$(arguments[0]).tree('selectNode', node)".format(node_locate=node_locate)
        return self._execute_script(script, self._get_web_element())

    def __get_datasource(self, loop: int = 5, sleep: int = 0.1):
        datasource = None
        for index in range(1, loop + 1):
            time.sleep(sleep)
            script = "return $(arguments[0]).tree('getNodes')"
            datasource = self._execute_script(script, self._get_web_element())
            if datasource:
                break
        return datasource

    def __get_option(self, option):
        script = "return $(arguments[0]).tree('option','{0}')".format(option)
        return self._execute_script(script, self._get_web_element())

    def get_identification(self):
        identification = {'data-ui-role': ['tree']}
        return identification